package com.yonyou.pmclouds.basecom.bp.template;

import com.yonyou.pmclouds.basecom.dao.BaseMapper;
import com.yonyou.pmclouds.basecom.entity.Entity;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.ConcurrentOperationException;
import com.yonyou.pmclouds.basecom.exception.DataModifiedException;
import com.yonyou.pmclouds.basecom.lock.AutoReleaseLockUtil;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.ChangeFlagCheckUtil;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import java.util.HashMap;
import java.util.HashSet;

/**
 * @author chulf
 * @date 2020/4/15
 * @des 批删模板
 */
public class MultiDeleteBpTemplate<T extends Entity> extends MultiOperateBpTemplate<T> {
    private static final String[] DR_FIELDS = new String[]{CommonFieldConst.DR};
    private BaseMapper<T> mapper;
    private boolean compareChanageFlag;

    public MultiDeleteBpTemplate(BaseMapper<T> mapper,boolean compareChangeFlag) {
        this.mapper = mapper;
        this.compareChanageFlag = compareChangeFlag;
    }

    @Override
    protected T[] getOrigVO(T[] vo) throws BusinessException {

        String[] ids = getPks(vo);
        String pksSql = getPksSql(ids);
        T[] origVO = mapper.getByBillIds(pksSql);
        HashMap<String, Object> pk2Object = new HashMap<>();
        for (T t : origVO) {
            pk2Object.put(t.pkFiledValue().toString(),t);
        }

        for (T temp: vo) {
            // lock
            if (!AutoReleaseLockUtil.addAutoReleaseLock(temp.pkFiledValue().toString())) {
                throw new ConcurrentOperationException();
            }
            // get&check
            if (compareChanageFlag) {
                Object orig = pk2Object.get(temp.pkFiledValue().toString());
                if (!ChangeFlagCheckUtil.isSameFlag(temp, orig)) {
                    throw new DataModifiedException();
                }
            }
        }

        return origVO;
    }
    @Override
    protected void operateDirect(T[] vos, T[] origs) {
        T vo = vos[0];
        BeanHelper.setProperty(vo, CommonFieldConst.DR, (byte) 1);
        mapper.batchUpdateFieldsByPks(vo,DR_FIELDS,getPks(vos));
    }

    public T[] delete(T[] vo) throws BusinessException {
        return execute(vo);
    }

    private String getPksSql(String[] pks) {
        StringBuffer sql = new StringBuffer();
        for (String pk : pks) {
            sql.append("'"+pk+"'");
            sql.append(",");
        }
        String finalSql = sql.substring(0, sql.length() - 1);
        return finalSql;
    }
    private String[] getPks(T[] vos){
        HashSet<String> ids = new HashSet<>();
        for (T t : vos) {
            ids.add(t.pkFiledValue().toString());
        }
        if (ids.isEmpty()) return null;

        return ids.toArray(new String[0]);
    }


}
